package cn.collin.commons.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.log4j.Logger;

/**
 * 
 * 文件处理和文件上传工具类
 * 
 * @author collin.code@gmail.com
 * 
 */
public class FileUtils {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(FileUtils.class);

	/**
	 * 把commons upload上传的fileitem list内容根据属性名称对应关系复制到bean中
	 * @param encode form提交字段的编码
	 */
	public static FileItem populate(Object bean, List items,String encode)
			throws IllegalAccessException, InvocationTargetException,
			UnsupportedEncodingException {
		FileItem fileItem = null;
		for (Iterator iter = items.iterator(); iter.hasNext();) {
			FileItem item = (FileItem) iter.next();
			if (!item.isFormField()) {
				fileItem = item;
			} else {
				String fieldName = item.getFieldName();
				BeanUtils.setProperty(bean, fieldName, item.getString(encode));
			}
		}
		return fileItem;
	}

	private static Map filePropertiesMap = new HashMap();

	/**
	 * 把文件写到根目录下的一个目录中，如果目录中的文件超过一定数量，则新建一个目录
	 */
	public static FileMeta writeFileItemAverage(FileItem item,
			String rootFilePath, String rootWebPath) {
		if (null == item || item.getSize() == 0) {
			return new FileMeta();
		}
		FileMeta meta = null;
		try {
			Object obj = filePropertiesMap.get(rootFilePath);
			Properties props;
			if (obj == null) {
				props = new Properties();
				props.load(new FileInputStream(rootFilePath
						+ System.getProperty("file.separator")
						+ "file.properties"));
				filePropertiesMap.put(rootFilePath, props);
			} else {
				props = (Properties) obj;
			}
			int maxFileAmount = Integer.parseInt(props
					.getProperty("maxFileAmount"));
			int nextFileIndex = Integer.parseInt(props
					.getProperty("nextFileIndex"));
			int currentDirName = Integer.parseInt(props
					.getProperty("currentDirName"));

			if (nextFileIndex > maxFileAmount) {
				// new dir
				File dir = new File(rootFilePath
						+ System.getProperty("file.separator")
						+ (currentDirName + 1));
				dir.mkdir();
				nextFileIndex = 1;
				currentDirName = currentDirName + 1;
				props.put("currentDirName", currentDirName + "");
			}

			String[] sa = item.getName().split("[.]");
			String fileType = sa[sa.length - 1].toLowerCase();
			String uuid = IDGenerator.generateUUID();
			String fileName = uuid + "." + fileType;
			String filePath = rootFilePath
					+ System.getProperty("file.separator") + currentDirName
					+ System.getProperty("file.separator") + fileName;

			String oN = "";
			String[] n = item.getName().split(
					"\\" + System.getProperty("file.separator"));
			oN = n[n.length - 1];
			oN = oN.substring(0, oN.lastIndexOf("."));

			String webPath = rootWebPath + "/" + currentDirName + "/"
					+ fileName;

			meta = new FileMeta(oN, fileType, filePath, webPath, item.getSize());

			java.io.File file = new java.io.File(filePath);
			item.write(file);
			item.delete();

			props.put("nextFileIndex", nextFileIndex + 1 + "");
			props
					.store(
							new FileOutputStream(
									(rootFilePath
											+ System
													.getProperty("file.separator") + "file.properties")),
							"");
			filePropertiesMap.put(rootFilePath, props);
		} catch (Exception e) {
			logger.error("gen File error:" + e, e);
			throw new RuntimeException(e);
		} finally {
			item.delete();
		}
		return meta;

	}

	/**
	 * 从fileItem list中取出时间字段
	 * 
	 * @param items
	 * @param fieldName
	 * @param pattern
	 * @return
	 * @throws ParseException
	 */
	public static Timestamp getFieldValueWithTimestamp(List items,
			String fieldName, String pattern) throws ParseException {
		for (Iterator iter = items.iterator(); iter.hasNext();) {
			FileItem item = (FileItem) iter.next();
			if (item == null)
				return null;
			if (item.isFormField()
					&& item.getFieldName().equalsIgnoreCase(fieldName)) {
				if (item.getString().trim().length() == 0)
					return null;
				return new Timestamp(DateUtils.parse(item.getString(), pattern)
						.getTime());
			}
		}
		return null;
	}

}
